//Cyclone-Portal
//GAM 450 Final Project
//Gregory Dillon, Brian Gates, Kyle Chmielewski
//e_portal.cpp
//holds the gameSetup/gameInit/gameFinal, qemain.cpp files
//all initializes, global portal/particle declarations are held here

#include "config.h"
#if BUILD_PORTAL // compile this app

////////////////////////////////////////////////////////////////////////////////
// Header

#include "qec.h" // engine interface
#include "demoncore.h" // DePaul's core library
#include "portal.h"
#include "ParticleSystem.h"

// defines here

////////////////////////////////////////////////////////////////////////////////
// Game Struct
// JFL 07/29/06
struct 
{
   // pointers to instances, elements zero if not valid
   Portal *objInstance[2]; 
   ParticleSystem *partSys[1];
} Game; // Game

////////////////////////////////////////////////////////////////////////////////
// Game Functions

//gameStartFrame():
// initial frame setup drawing axes and grid
int gameStartFrame()
{
   qefnDrawAxes(1); // draw origin's axes
   qefnDrawGrid(50,1); // draw 50x50 grid with 1x1 unit squares

   glPolygonMode(GL_FRONT,GL_LINE); // draw wireframe polygons
   glCullFace(GL_BACK); // don't draw back faces
   glEnable(GL_CULL_FACE); // don't draw back faces

   return 0;
} // gameStartFrame()


//gameMainLoop():
// main loop- run through particle/portal objects updating and drawing them
int gameMainLoop()
{
   int i;
   Portal *portal;
   ParticleSystem *particles;
   CollisionSphere sphere;
   CollisionPlane plane;
   CollisionData data;

   gameStartFrame(); // setup defaults and draw grid

   particles = Game.partSys[0];

   particles->update();


   // run through all instances of objects, draw
   for(i=0;i<NUM(Game.objInstance);i++)
   {
      portal = Game.objInstance[i]; // set reference
      if(!(portal=Game.objInstance[i]))
         continue; // element empty, skip


      Portal *temp1 = Game.objInstance[0];
      Portal *temp2 = Game.objInstance[1];

      portal->draw(); // objects draw themselves
      portal->drawNormal();
      //glPopMatrix();
   } // for

   Vector3 temp1 = vecToVector(Game.objInstance[0]->xyzPortal);
   Vector3 temp2 = vecToVector(Game.objInstance[1]->xyzPortal);

   for(i=0;i<NUM(Game.partSys);i++)
   {
      particles = Game.partSys[i]; // set reference
      if(!(particles = Game.partSys[i]))
         continue; // element empty, skip
      //if (obj->spherePlaneCollision(obj2))   
      //{  
         particles->display(temp1, temp2); // objects draw themselves
   } // for

   return 0;
} // gameMainLoop()

// sets up the Portal and Thing objects
int gameSetup()
{
   int i;
   Portal *obj;
   ParticleSystem *obj2;
   float xx,zz; // used for Portal velocity
   xx = 0;
   zz = 0;

   // run through and create elements
   for(i=0;i<NUM(Game.objInstance);i++)
   {
      // create Portal
      if(!(obj = new Portal(i)))
      {
         BRK(); // error
         break; // exit loop
      }

      Game.objInstance[i]=obj; // set reference
      
      if(obj == Game.objInstance[0])
      {
         // first 2 Portals are blue
         obj->colorPortal[0] = 0; 
         obj->colorPortal[1] = 0;
         obj->colorPortal[2] = 1;

         obj->upVector = Vec3(obj->xyzPortal.x,obj->xyzPortal.y + 1,obj->xyzPortal.z);
         if(i==0)
            obj->rightVector = Vec3(obj->xyzPortal.x + 1, obj->xyzPortal.y, obj->xyzPortal.z);
         else
            obj->rightVector = Vec3(obj->xyzPortal.x - 1, obj->xyzPortal.y, obj->xyzPortal.z);
         obj->normal = obj->rightVector.cross(obj->upVector);
         obj->xyzPortal.set(0, 5, 5);
      }
      else
      {
         // the rest are grey
         obj->colorPortal[0] = 1;
         obj->colorPortal[1] = 0;
         obj->colorPortal[2] = 0;
         obj->upVector = Vec3(obj->xyzPortal.x, obj->xyzPortal.y + 1, obj->xyzPortal.z);
         if(i==0)
            obj->rightVector = Vec3(obj->xyzPortal.x + 1, obj->xyzPortal.y, obj->xyzPortal.z);
         else
            obj->rightVector = Vec3(obj->xyzPortal.x - 1, obj->xyzPortal.y, obj->xyzPortal.z);
         obj->normal = obj->rightVector.cross(obj->upVector);
         obj->xyzPortal.set(0, 5, -5);
      } // else
   }

   // run through and create elements
   for(i=0;i<NUM(Game.partSys);i++)
   {
      // create Portal
      obj2 = new ParticleSystem();
      if(!(obj2 = new ParticleSystem()))
      {
         BRK(); // error
         break; // exit loop
      }
      

      Game.partSys[i] = obj2; // set reference
      
      if(obj2 == Game.partSys[0])
      {
         // first 2 Portals are blue
         //obj2->colorPortal[0] = 0; 
         //obj2->colorPortal[1] = 0;
         //obj2->colorPortal[2] = 1;
         //obj2->xyzPortal.set(0, 5, 5);
         obj2->setPos(5, 5, 5);
      }
   }

   return 0;
} // gameSetup()

// JFL 07/22/09
int gameInit()
{
   MEMZ(Game); // initialize game globals to zero
   return 0; // return negative error code only w/catastrophic failure
} // gameInit()

// JFL 07/22/09
void gameFinal()
{
   int i;
   Portal *obj;
   ParticleSystem *obj2;

   // run through all the elements in the array
   for(i=0;i<NUM(Game.objInstance);i++)
   {
      if(!(obj=Game.objInstance[i]))
         continue; // element empty, skip
      obj->zap(); // delete
      Game.objInstance[i]=0; // clear reference
   } // for

   for(i=0;i<NUM(Game.partSys);i++)
   {
      if(!(obj2 = Game.partSys[i]))
         continue; // element empty, skip
      obj2 = 0; // delete
      //Game.partSys[i]=0; // clear reference
   } // for

} // gameFinal()

////////////////////////////////////////////////////////////////////////////////
// Main

int qeMain(int argc,chr *argv[])
{
   int fail=0; // failure

   // INIT

   qePrintf("%s / %s / %s\n",__FILE__,glGetString(GL_VERSION),qeVersion());

   if(gameInit()<0) // initialize game
   {
      fail=1;
   } // if

   if(fail) // check for catastrophic failure in init
   {
      goto BAIL; // end
   } // if

   // BODY

   // add a function object to engine
   if(!qeObjAddFnc(gameMainLoop))
   {
      BRK(); // error
      goto BAIL; // end
   }

   gameSetup(); // setup game objects
 
   qeForever(); // turn over control to the engine until the program exits

BAIL:

   // FINAL

   gameFinal(); // cleanup and free game objects

   if(qefnCheckForCleanExit()<0)
   {
      BRK(); // check qelog.txt for problem
   } // if

   return 0;
} // qeMain()

#endif // compile this app
// EOF
